package cn.tedu.ivos.audit.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.dto.AuditQuery;
import cn.tedu.ivos.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivos.audit.pojo.entity.Audit;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.ApplicationStatusEnum;
import cn.tedu.ivos.base.enums.AuditStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Transactional
@Slf4j
@Service
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    ApplicationMapper applicationMapper;

    @Override
    public void insertAudit(Application application) {
        log.debug("为传入的申请单创建对应的审批单:application={}", application);
        //1.获取审批人id集合
        List<Long> userIdList = application.getAuditUserIdList();
        //2.遍历上方的审批人id集合,为每一个审批人创建一条审批单数据
        for (int i = 0; i < userIdList.size(); i++) {
            Audit audit = new Audit();
            //3.设置本条审批单的数据
            audit.setApplicationId(application.getId());//申请单id
            audit.setAuditUserId(userIdList.get(i));//审批人id
            audit.setAuditSort(i);//审批次序
            if(i == 0){//当前新建的是第1条审批数据,第一个审批人的状态是"待我审核"
                audit.setAuditStatus(AuditStatusEnum.MY_PENGDING.getCode());
            }else{//其他人的审批状态都是"待他人审核"
                audit.setAuditStatus(AuditStatusEnum.PENGDING.getCode());
            }
            audit.setCreateTime(new Date());//创建时间
            auditMapper.insert(audit);
        }
    }

    @Override
    public List<AuditVO> selectAuditByApplicationId(Long id) {
        log.debug("根据传入的申请单id查询对应的审批单:id={}", id);
        return auditMapper.selectAuditByApplicationId(id);
    }

    @Override
    public List<AuditVO> selectAudit(AuditQuery auditQuery) {
        log.debug("查询审批单业务:auditQuery={}", auditQuery);
        List<AuditVO> list = auditMapper.selectAudit(auditQuery);
        /* 需要遍历出每一个审批单VO为其补全审批人数据 */
        for(int i = 0; i < list.size(); i++){
            AuditVO auditVO = list.get(i);
            assignAuditUserList(auditVO);
        }
        return list;
    }

    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        log.debug("审批单业务:{}", auditSaveParam);
        /* 1.更新当前审批单的状态 */
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveParam, audit);//auditStatus(30/40) auditId rejectReason
        audit.setUpdateTime(new Date());
        auditMapper.update(audit);
        /* 2.更新此审批单对应的申请单的状态 */
        Application application = new Application();
        application.setId(audit.getApplicationId());
        application.setUpdateTime(new Date());
        /* 3.判断当前是审批通过还是驳回,分别针对不同的审批处理做不同的后续操作 */
        if(audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())){//审批通过
            //需要继续查其他的审批单
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //看看是否有未审批的审批单,如果有未审批的审批单,申请单是审核中,改为30
            //如果没有未审批的审批单,申请单是已审核,改为50
            Integer count = auditMapper.selectRestAuditCount(auditQuery);
            if(count>0){//还有未审核的数据
                auditQuery.setAuditSort(audit.getAuditSort()+1);
                List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
                if(auditVOList !=null && auditVOList.size()>0){
                    AuditVO auditVO = auditVOList.get(0);
                    //开始更新第2条审批单
                    Audit audit2 = new Audit();
                    audit2.setId(auditVO.getId());
                    audit2.setAuditStatus(AuditStatusEnum.MY_PENGDING.getCode());
                    audit2.setUpdateTime(new Date());
                    auditMapper.update(audit2);
                }
                //还需要设置申请单的状态为"审核中"
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.update(application);
            }else{//没有未审核的审批单了
                application.setStatus(ApplicationStatusEnum.AUDITED.getCode());
                applicationMapper.update(application);
            }
        }else{//审批驳回
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
            //判断是否查到了数据,如果查到了,依次遍历每个审批单对象,如果审批状态为"待他人审核",就删除
            if(auditVOList != null && auditVOList.size()>0){
                for(int i = 0; i < auditVOList.size(); i++){
                    AuditVO auditVO = auditVOList.get(i);
                    if(auditVO.getAuditStatus().equals(AuditStatusEnum.PENGDING.getCode())){
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            //设置申请单的状态为驳回
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.update(application);
        }
    }

    private void assignAuditUserList(AuditVO auditVO) {
        //1.准备空集合用于存放审批人姓名与id
        List<String> auditUsernameList = new ArrayList<>();
        List<Long> auditUserIdList = new ArrayList<>();
        //2.获取当前审批单对应的申请单id,再进一步获取批此申请单的所有审批单
        List<AuditVO> auditVOList =
                auditMapper.selectAuditByApplicationId(auditVO.getApplicationId());
        //3.遍历审批单VO,获取每个审批VO中的审批人数据
        for(int i = 0; i < auditVOList.size(); i++){
            Long userId = auditVOList.get(i).getAuditUserId();
            auditUserIdList.add(userId);
            UserVO user = userMapper.selectById(userId);
            auditUsernameList.add(user.getUsername());
        }
        StringJoiner stringJoiner = new StringJoiner(",");
        for(String username : auditUsernameList){
            stringJoiner.add(username);
        }
        //4.为传入的申请单VO补全数据
        auditVO.setAuditUserIdList(auditUserIdList);
        auditVO.setAuditUsernameList(stringJoiner.toString());
    }
}








